package com.tanhua.server.service;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.dubbo.config.annotation.Reference;

import com.alibaba.fastjson.JSON;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.tanhua.common.enums.SexEnum;
import com.tanhua.common.pojo.User;
import com.tanhua.common.pojo.UserInfo;
import com.tanhua.common.utils.UserThreadLocal;
import com.tanhua.dubbo.server.api.VoiceApi;

import com.tanhua.dubbo.server.pojo.Voice;
import com.tanhua.server.vo.VoiceVo;
import org.apache.commons.lang3.RandomUtils;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static com.tanhua.common.enums.SexEnum.*;

/**
 * @Author fenda xu
 * @Date 2021 3/29/21 10:28 AM
 * @Version 1.0
 */
@Service
public class VoiceService {
    @Autowired
    private FdfsWebServer fdfsWebServer;

    @Autowired
    private FastFileStorageClient fastFileStorageClient;

    @Reference(version = "1.0.0")
    private VoiceApi voiceApi;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private UserInfoService userInfoService;

    @Value("${voiceUser}")
    private String voiceUser;


    /**
     * 保存语音
     *
     * @param soundFile
     * @return
     */
    public Boolean saveVoice(MultipartFile soundFile) {
        if (soundFile == null) {
            return false;
        }
        User user = UserThreadLocal.get();
        Voice voice = new Voice();
        voice.setUserid(user.getId());

        //上传语音到fastDFS中
        try {
            StorePath storePath = fastFileStorageClient.uploadFile(soundFile.getInputStream(), soundFile.getSize(),
                    //切割后缀
                    StrUtil.subAfter(soundFile.getOriginalFilename(), '.', true), null);

            voice.setSoundFileUrl(fdfsWebServer.getWebServerUrl() + storePath.getFullPath());

            Boolean boo = this.voiceApi.saveVoice(voice);
            return boo;

        } catch (IOException e) {
            e.printStackTrace();
        }

        return false;
    }

    /**
     * 查询获得vo对象返回控制器
     *
     * @return
     */
    public VoiceVo acceptVoice() {
        User user = UserThreadLocal.get();
        Long userId = user.getId();//当前登陆用户id
        //查询数据库里的所有语音集合
//        List<Voice> voiceList = voiceApi.getVoice();
        Voice voice = removeVoice();//获取筛选好的一条语音

        //前台需要一个vo对象
        UserInfo userInfo = userInfoService.queryUserInfoByUserId(voice.getUserid());

        if (userInfo == null) {
            return null;

        }
        VoiceVo voiceVo = new VoiceVo();

        voiceVo.setId(Integer.valueOf(voice.getUserid().toString()));
        voiceVo.setAge(userInfo.getAge());
        voiceVo.setAvatar(userInfo.getLogo());
        voiceVo.setNickname(userInfo.getNickName());
        voiceVo.setSoundUrl(voice.getSoundFileUrl());
        voiceVo.setGenger(userInfo.getSex().equals(MAN) ? "man" : "woman");
        //定义redis的key      接收语音
        String redisKey = "acceptVoice_" + userId;//接收语音的用户key

        if (this.redisTemplate.hasKey(redisKey)) {
            //有
            int num = redisTemplate.opsForValue().decrement(redisKey).intValue();//递减
            if (num == 0) {
                return null;
            }
            voiceVo.setRemainingTimes(num);
            System.out.println(num);
            System.out.println(voiceVo.getRemainingTimes());
        } else {
            //没有
            DateTime now = DateTime.now();//获取当前接收语音时间
            DateTime day = DateUtil.endOfDay(now); //获取这天的结束时间

            long time = DateUtil.betweenMs(now, day) / 1000;//判断两个时间相差的毫秒数

            //设置变量值的过期时间。
            redisTemplate.opsForValue().set(redisKey, "5", time, TimeUnit.SECONDS);
            voiceVo.setRemainingTimes(5);
        }

        String yitingredisKey = "yitingyuyin" + "_" + voice.getId().toHexString() + "_" + userId;//已经听过的语音的id
        redisTemplate.opsForValue().set(yitingredisKey, "1");
        return voiceVo;
    }

    /**
     * 筛选语音
     *
     * @return
     */
    public Voice removeVoice() {

        List<Voice> voiceList = voiceApi.getVoice();
        Long id = UserThreadLocal.get().getId();//当前登陆用户的id
        UserInfo userInfo = userInfoService.queryUserInfoByUserId(id);
        SexEnum sexEnum = userInfo.getSex();
        List<Voice> arrayList = new ArrayList<>();
        if (sexEnum.equals(MAN)) {
            for (int i = 0; i < voiceList.size(); i++) {
                Long userid = voiceList.get(i).getUserid();//获取每一条语音的用户的id；
                SexEnum sex = userInfoService.queryUserInfoByUserId(userid).getSex();
                if (sex.equals(WOMAN)) {
                    //已经听过的语音
                    String yitingredisKey = "yitingyuyin" + "_" + voiceList.get(i).getId().toHexString() + "_" + id;//已经听过的语音的id
                    if (!redisTemplate.hasKey(yitingredisKey)) {
                        arrayList.add(voiceList.get(i));
                    }
                }
            }
       /* List<Voice> list = new ArrayList<>();
        for (int i = 0; i < voiceList.size(); i++) {
            ObjectId voiceId = voiceList.get(i).getId();//
            // 获取每一条语音的id；
            //已经听过的语音
            String yitingredisKey = "yitingyuyin"+"_"+voiceId.toHexString()+"_"+id;//已经听过的语音的id
            if (voiceList.get(i).getUserid() != id && !redisTemplate.hasKey(yitingredisKey)) {
                list.add(voiceList.get(i));
            }
        }


        int index = RandomUtils.nextInt(0, list.size());
        Voice voice = voiceList.get(index);

        return voice;*/
        } else if (sexEnum.equals(WOMAN)) {

            for (int i = 0; i < voiceList.size(); i++) {
                Long userid = voiceList.get(i).getUserid();//获取每一条语音的用户的id；
                SexEnum sex = userInfoService.queryUserInfoByUserId(userid).getSex();
                if (sex.equals(MAN)) {
                    //已经听过的语音
                    String yitingredisKey = "yitingyuyin" + "_" + voiceList.get(i).getId().toHexString() + "_" + id;//已经听过的语音的id
                    if (!redisTemplate.hasKey(yitingredisKey)) {
                        arrayList.add(voiceList.get(i));
                    }
                }
            }
        } else if (sexEnum.equals(UNKNOWN)) {
            for (int i = 0; i < voiceList.size(); i++) {
                Long userid = voiceList.get(i).getUserid();//获取每一条语音的用户的id；

                //已经听过的语音
                String yitingredisKey = "yitingyuyin" + "_" + voiceList.get(i).getId().toHexString() + "_" + id;//已经听过的语音的id
                if (voiceList.get(i).getUserid() != id && !redisTemplate.hasKey(yitingredisKey)) {
                    arrayList.add(voiceList.get(i));
                }
            }

        }
        int index = RandomUtils.nextInt(0, arrayList.size());
        Voice voice = arrayList.get(index);
        return voice;
    }

    /**
     * 筛选语音,增强版
     *
     * @return
     */
    public Voice removeVoice2() {
        Long userId = UserThreadLocal.get().getId();
        UserInfo userInfo = userInfoService.queryUserInfoByUserId(userId);
        //查询所有的语音id
        String voiceIds = redisTemplate.opsForValue().get("voices");
        if (StringUtils.isEmpty(voiceIds)) {
            //如果没有 那么去数据库查 然后保存到缓存中
            //查所有供大家使用
            List<Voice> voice = voiceApi.getVoice();
            List<Object> vids = CollUtil.getFieldValues(voice, "vid");
            //转为字符串，不然无法保存
            String vidsstr = JSON.toJSONString(vids);
            voiceIds = vidsstr;
            redisTemplate.opsForValue().set("voice", vidsstr);
        }

        String substring = voiceIds.substring(1, voiceIds.length() - 1);
        String[] split = substring.split(",");


        for (int j = 0; j < split.length; j++) {
            String s = split[j];
            Voice voice = voiceApi.getVoiceByVid(s);
            UserInfo voiceUser = userInfoService.queryUserInfoByUserId(voice.getUserid());
//            System.out.println(videoUser);
            if (userInfo.getSex().getValue() != voiceUser.getSex().getValue() && !redisTemplate.hasKey(voice.getVid() + "_" + userId)) {
                //记录语音已被当前用户听取
                redisTemplate.opsForValue().set(voice.getVid() + "_" + userId, "1");
                System.out.println("本次语音的ID"+s);
                String[] remove = ArrayUtil.remove(split, j);
                String removeStr = JSON.toJSONString(remove);
                redisTemplate.opsForValue().set("voice", removeStr);
                return voice;
            }
        }
        //都是同性  给默认值
        Voice voice = voiceApi.getVoiceByVid(voiceUser);
        return voice;
    }

    @Scheduled(cron = "0/30 * * * * ? ")
    public void flushVoice() {
        //定时拉取最新的语音
        List<Voice> voiceList = voiceApi.getVoiceByCreated();
        List<Object> vid = CollUtil.getFieldValues(voiceList, "vid");
        String vidIds = JSON.toJSONString(vid);
        redisTemplate.opsForValue().set("voices", vidIds);
    }
}
